package hasthi.manager.gui;

import hasthi.common.HasthiException;
import hasthi.common.RemoteProcessorException;
import hasthi.common.constants.HasthiConstants;
import hasthi.metamodel.resource.ManagedResource;
import hasthi.metamodel.resource.ManagedResource.ResourceType;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTree;
import javax.swing.tree.TreeSelectionModel;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ManagementGUI {
    private static Log log = LogFactory.getLog(HasthiConstants.LOGGER_NAME);
    // private ResourceModel resourceModel;
    private JFrame frame;
    private ResourceTreeModel resourceTreeModel;
    private UIContext uicontext;
    private JTabbedPane tabbedPane;
    private MoniteringPannel monitoringPannel;

    public void initGUI(String bootstrapNode) throws HasthiException {
        // Make sure we have nice window decorations.
        JFrame.setDefaultLookAndFeelDecorated(true);

        // Create and set up the window.
        frame = new JFrame("Service Monitoring GUI");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(new Dimension(500, 500));

        // Add the ubiquitous "Hello World" label.
        // JPanel panel = new JPanel(new BorderLayout() );
        // JLabel label = new JLabel("Monitor");
        // panel.add(label,BorderLayout.NORTH);
        //        

        // resourceModel = new DummyResourceModel(20);

        uicontext = new UIContext(false,bootstrapNode);

        ResourcePannel pannel = new ResourcePannel();

        resourceTreeModel = new ResourceTreeModel(pannel, uicontext);
        JTree tree = new JTree(resourceTreeModel);
        tree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);

        // Listen for when the selection changes.
        tree.addTreeSelectionListener(resourceTreeModel);
        tree.addMouseListener(createPopupListener());

        // if (playWithLineStyle) {
        // System.out.println("line style = " + lineStyle);
        // tree.putClientProperty("JTree.lineStyle", lineStyle);
        // }

        // Create the scroll pane and add the tree to it.
        JScrollPane treeView = new JScrollPane(tree);

        // Create the HTML viewing pane.
        // JEditorPane htmlPane = new JEditorPane();
        // htmlPane.setEditable(false);
        // JScrollPane htmlView = new JScrollPane(htmlPane);

        // Add the scroll panes to a split pane.
        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
        splitPane.setTopComponent(treeView);

        monitoringPannel = new MoniteringPannel();
        tabbedPane = new JTabbedPane();
        tabbedPane.addTab("Monitoring", monitoringPannel);
        tabbedPane.addTab("Resource", pannel);

        tabbedPane.addTab("Errors", uicontext.getOutputConsole());

        frame.setJMenuBar(createMenu());

        splitPane.setBottomComponent(tabbedPane);

        Dimension minimumSize = new Dimension(100, 50);
        pannel.setMinimumSize(minimumSize);
        treeView.setMinimumSize(minimumSize);
        splitPane.setDividerLocation(400);
        splitPane.setPreferredSize(new Dimension(550, 300));

        Dimension d = frame.getToolkit().getScreenSize();

        // Add the split pane to this panel.
        frame.getContentPane().add(splitPane);
        // frame.getContentPane().add(new MoniteringPannel(resourceModel));
        frame.setSize(d.width * 6 / 7, d.height * 6 / 7);
        // Display the window.
        // frame.pack();
        frame.setVisible(true);
    }

    private JMenuBar createMenu() {
        JMenuBar bar = new JMenuBar();
        JMenu menu1 = new JMenu("Base");
        JMenuItem mitem = new JMenuItem("Reload");
        mitem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    resourceTreeModel.loadAllResources();
                    resourceTreeModel.signalTreeChange();
                } catch (HasthiException e1) {
                    e1.printStackTrace();
                }
            }
        });
        menu1.add(mitem);
        mitem = new JMenuItem("Exit");
        mitem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    monitoringPannel.removeSubscription();
                } catch (HasthiException e1) {
                    log.error(e1);
                }
                System.exit(0);
            }
        });
        menu1.add(mitem);
        bar.add(menu1);

        JMenu menu2 = new JMenu("Tools");
        mitem = new JMenuItem("ShutDown All Services");
        mitem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    ActionPanel.shutDownAllServices(uicontext);
                } catch (HasthiException e1) {
                    log.error(e1);
                }
            }
        });
        menu2.add(mitem);
        mitem = new JMenuItem("Restart All Services");
        mitem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    ActionPanel.restartAllServices(uicontext);
                } catch (HasthiException e1) {
                    log.error(e1);
                }
            }
        });
        menu2.add(mitem);
        mitem = new JMenuItem("ShutDown All App Services");
        mitem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    ActionPanel.shutDownAllAppServices(uicontext);
                } catch (HasthiException e1) {
                    log.error(e1);
                }
            }
        });
        menu2.add(mitem);
        mitem = new JMenuItem("Gloabl Config");
        mitem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                // TODO
            }
        });
        menu2.add(mitem);

        mitem = new JMenuItem("ShowActions");
        mitem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    tabbedPane.addTab("ActionPanel", new ActionPanel(uicontext));
                } catch (HasthiException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }
        });
        menu2.add(mitem);
        bar.add(menu2);

        JMenu menu3 = new JMenu("Test");
        mitem = new JMenuItem("KillManager");
        mitem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    String[] possibilities = new String[uicontext.getManagers().size()];
                    for (int i = 0; i < possibilities.length; i++) {
                        possibilities[i] = uicontext.getManagers().get(i).getManagerAddress()
                                .getSoapAddress();
                    }
                    String s = (String) JOptionPane.showInputDialog(frame, "KillManager",
                            "Select Manager to Kill", JOptionPane.PLAIN_MESSAGE, null,
                            possibilities, possibilities[0]);

                    // If a string was returned, say so.
                    if ((s != null) && (s.length() > 0)) {
                        ActionPanel.sendShutdownMessage(uicontext, s);
                    }
                } catch (HasthiException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }
        });
        menu3.add(mitem);
        mitem = new JMenuItem("KillCoordinator");
        mitem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    ActionPanel.sendShutdownMessage(uicontext, uicontext.getCoordinatorUrl());
                } catch (RemoteProcessorException e1) {
                    e1.printStackTrace();
                } catch (HasthiException e1) {
                    e1.printStackTrace();
                }
            }
        });
        menu3.add(mitem);

        mitem = new JMenuItem("KillResources");
        mitem.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                try {
                    String[] possibilities = new String[uicontext.getManagers().size()];
                    for (int i = 0; i < possibilities.length; i++) {
                        possibilities[i] = uicontext.getManagers().get(i).getManagerAddress()
                                .getSoapAddress();
                    }
                    String s = (String) JOptionPane.showInputDialog(frame,
                            "Number of resources to Kill?");

                    // If a string was returned, say so.
                    if ((s != null) && (s.length() > 0)) {
                        ManagedResource[] resources = uicontext.getExternalResourceModel()
                                .getAllResources();
                        int resourceCount = Integer.parseInt(s);
                        int stoppedResourceCount = 0;
                        for (int i = 0; i < resources.length
                                && stoppedResourceCount < resourceCount; i++) {
                            if (!resources[i].getCategory().equals(ResourceType.Host.toString())) {
                                ActionPanel.sendShutdownMessage(uicontext, resources[i].getManagerAgentURL());
                                stoppedResourceCount++;
                            }
                        }
                    }
                } catch (HasthiException e1) {
                    // TODO Auto-generated catch block
                    e1.printStackTrace();
                }
            }
        });
        menu3.add(mitem);
        bar.add(menu3);

        return bar;

    }

    // public static JPanel createPanel(){

    // JPanel host1 = new JPanel(new FlowLayout());
    // host1.setBorder(BorderFactory.createTitledBorder("host1"));
    // hostPanel.add(host1);
    //      
    // for(int i=0;i<3;i++){
    // host1.add(new JLabel("string"+i));
    //          
    // }
    //      
    //      
    // ImageIcon sIcon = new ImageIcon("src/images/service.gif");
    // JLabel l1 = new JLabel();
    // l1.setIcon(sIcon);
    // host1.add(l1);
    //      
    // JPanel host2 = new JPanel(new FlowLayout());
    // host2.setBorder(BorderFactory.createTitledBorder("host2"));
    // hostPanel.add(host2);
    //      
    // for(int i=0;i<3;i++){
    // host2.add(new JLabel("string"+i));
    // }
    // return panel;
    //      
    // }

    // ImageIcon convertIcon = createImageIcon("images/convert.gif",
    // "Convert temperature")

    public void update() {
        frame.repaint();
    }

    public MouseAdapter createPopupListener() {
        // ...where instance variables are declared:
        final JPopupMenu popup = new JPopupMenu();

        // ...where the GUI is constructed:
        // Create the popup menu.

        JMenuItem menuItem = new JMenuItem(ActionPanel.ResourceActions.Stop.toString());
        menuItem.setActionCommand(ActionPanel.ResourceActions.Stop.toString());
        final ActionListener actionListener = new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JPopupMenu parent = (JPopupMenu) ((JMenuItem) e.getSource()).getParent();
                JTree tree = (JTree) parent.getInvoker();
                ResourceNode node = (ResourceNode)tree.getLastSelectedPathComponent();
                if(node != null){
                    ActionPanel.execuateActionOnResource(uicontext, 
                            ActionPanel.ResourceActions.valueOf(e.getActionCommand()), node.getResource());
                }else{
                    log.info("No node selected");
                }
                System.out.println();
            }
        };
        menuItem.addActionListener(actionListener);
        popup.add(menuItem);
        menuItem = new JMenuItem("Restart");
        menuItem.addActionListener(actionListener);
        popup.add(menuItem);

        return new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                maybeShowPopup(e);
            }
            public void mouseReleased(MouseEvent e) {
                maybeShowPopup(e);
            }
            private void maybeShowPopup(MouseEvent e) {
                if (e.isPopupTrigger()) {
                    popup.show(e.getComponent(), e.getX(), e.getY());
                }
            }
        };
    }

    public static void main(String[] args) {
        try {
            String bootsrapNode = JOptionPane.showInputDialog("Input the Hasthi bootstrap Node", "tyr12.cs.indiana.edu");
            ManagementGUI gui = new ManagementGUI();
            gui.initGUI(bootsrapNode);
            gui.update();
        } catch (HasthiException e) {
            e.printStackTrace();
        }
    }
}
